package com.iknight.portal.reids;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.springframework.data.redis.connection.jedis.JedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.exceptions.JedisException;

public class RedisManage {

	private JedisConnectionFactory jedisConnectionFactory;

	private JedisPool jedisPool;

	private int expire;

	private Jedis getJedis() {
		Jedis jedis = null;
		JedisConnection jedisConn = null;
		if (null != jedisConnectionFactory) {
			jedisConn = jedisConnectionFactory.getConnection();
			jedis = jedisConn.getNativeConnection();
		} else if (null != jedisPool) {
			jedis = jedisPool.getResource();
		}

		return jedis;
	}

	/**
	 * 释放链接
	 * 
	 * @param jedis
	 * @param conectionBroken
	 */
	@SuppressWarnings("deprecation")
	private void revokeResource(Jedis jedis, boolean conectionBroken) {
		try {
			if (conectionBroken) {
				jedisPool.returnBrokenResource(jedis);
				jedis = null;
			} else {
				jedisPool.returnResource(jedis);
			}
		} catch (Exception e) {
			e.printStackTrace();
			// JedisUtils.destroyJedis(jedis);
		}
	}

	/**
	 * 判断异常类型
	 * 
	 * @param jedisException
	 * @return
	 */
	private boolean handleJedisException(JedisException jedisException) {
		if (jedisException instanceof JedisConnectionException) {
		} else if (jedisException instanceof JedisDataException) {
			if ((jedisException.getMessage() != null)
					&& (jedisException.getMessage().indexOf("READONLY") != -1)) {
			} else {
				return false;
			}
		} else {
			jedisException.printStackTrace();
		}
		return true;
	}

	public byte[] get(byte[] key) {
		byte[] value = null;
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			value = jedis.get(key);
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
		return value;
	}

	/**
	 * get value from redis
	 * 
	 * @param key
	 * @return
	 */
	public String get(String key) {
		String value = null;
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			value = jedis.get(key);
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
		return value;
	}

	/**
	 * set
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public byte[] set(byte[] key, byte[] value) {
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			jedis.set(key, value);
			if (this.expire != 0) {
				jedis.expire(key, this.expire);
			}
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
		return value;
	}

	/**
	 * set
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public String set(String key, String value) {
		Jedis jedis = getJedis();
		boolean broken = false;
		try {
			jedis.set(key, value);
			if (this.expire != 0) {
				jedis.expire(key, this.expire);
			}
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
		return value;
	}

	/**
	 * set
	 * 
	 * @param key
	 * @param value
	 * @param expire
	 * @return
	 */
	public byte[] set(byte[] key, byte[] value, int expire) {
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			jedis.set(key, value);
			if (expire != 0) {
				jedis.expire(key, expire);
			}
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
		return value;
	}

	/**
	 * set
	 * 
	 * @param key
	 * @param value
	 * @param expire
	 * @return
	 */
	public String set(String key, String value, int expire) {
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			jedis.set(key, value);
			if (expire != 0) {
				jedis.expire(key, expire);
			}
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} finally {
			revokeResource(jedis, broken);
		}
		return value;
	}

	/**
	 * del
	 * 
	 * @param key
	 */
	public void del(byte[] key) {
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			jedis.del(key);
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
	}

	/**
	 * del
	 * 
	 * @param key
	 */
	public void del(String key) {
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			jedis.del(key);
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
	}

	/**
	 * flush
	 */
	public void flushDB() {
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			jedis.flushDB();
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
	}

	/**
	 * size
	 */
	public Long dbSize() {
		Long dbSize = 0L;
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			dbSize = jedis.dbSize();
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
		return dbSize;
	}

	/**
	 * keys
	 * 
	 * @param regex
	 * @return
	 */
	public Set<byte[]> keys(String pattern) {
		Set<byte[]> keys = null;
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			keys = jedis.keys(pattern.getBytes());
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
		return keys;
	}

	public void dels(String pattern) {
		System.err.println(pattern);
		Set<String> keys = null;
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			keys = jedis.keys(pattern);
			Iterator<String> ito = keys.iterator();
			while (ito.hasNext()) {
				String key = ito.next();
				System.err.println(key);
				jedis.del(key);
			}
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
	}

	/**
	 * List
	 */
	/**
	 * 前置
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public Long lpush(String key, String value) {
		Long index = null;
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			index = jedis.lpush(key, value);
			if (this.expire != 0) {
				jedis.expire(key, this.expire);
			}
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
		return index;
	}

	public Long lpush(byte[] key, byte[] value) {
		Long index = null;
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			index = jedis.lpush(key, value);
			if (this.expire != 0) {
				jedis.expire(key, this.expire);
			}
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
		return index;
	}

	/**
	 * 追加
	 * 
	 * @param key
	 * @param value
	 * @return
	 */
	public Long rpush(String key, String value) {
		Long index = null;
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			index = jedis.rpush(key, value);
			if (this.expire != 0) {
				jedis.expire(key, this.expire);
			}
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
		return index;
	}

	public Long rpush(byte[] key, byte[] value) {
		Long index = null;
		Jedis jedis = null;
		boolean broken = false;
		try {
			jedis = getJedis();
			index = jedis.rpush(key, value);
			if (this.expire != 0) {
				jedis.expire(key, this.expire);
			}
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
		return index;
	}

	public List<String> lrange(String key) {
		Jedis jedis = null;
		boolean broken = false;
		List<String> result = null;
		try {
			jedis = getJedis();
			result = jedis.lrange(key, 0, -1);
		} catch (JedisException e) {
			broken = handleJedisException(e);
			throw e;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			revokeResource(jedis, broken);
		}
		return result;
	}

	public static void main(String[] args) {
		Jedis jedis = new Jedis("192.168.127.14", 6379);
		jedis.set("duwei:zhaochunfagn:nihao", "hahahahahaha");
		System.out.println(jedis.get("duwei:zhaochunfagn:nihao"));
		jedis.close();
	}
}
